`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: 
// 
// Create Date:    12:03:50 04/20/2011 
// Design Name: 
// Module Name:    Memory 
// Project Name: 
// Target Devices: 
// Tool versions: 
// Description: 
//
// Dependencies: 
//
// Revision: 
// Revision 0.01 - File Created
// Additional Comments: 
//
//////////////////////////////////////////////////////////////////////////////////
module Memory(clk, Branch, MemRead, MemWrite, zero, ALUresultIn, readData, doBra, mt, 
	RegWriteIn,	MemtoRegIn, writeDstIn, branchAddrIn, RegWriteOut, MemtoRegOut, ALUresultOut, 
	writeDstOut, branchAddrOut, reset);
	
	input clk;
	input Branch;
	input MemRead;
	input MemWrite;
	input zero;
	input [15:0] ALUresultIn;
	input [15:0] mt;
	input reset;
	output [15:0] readData;
	output doBra;
	
	//Just passing through
	input RegWriteIn, MemtoRegIn;
	input [3:0] writeDstIn;
	input [15:0] branchAddrIn;
	
	output RegWriteOut, MemtoRegOut;
	output [15:0] ALUresultOut;
	output [3:0] writeDstOut;
	output [15:0] branchAddrOut;
	
	//Buffers added to safeguard against hold violations
	delay_buffer_1bit i_buf1(.a(RegWriteIn), .y(RegWriteOut));
	delay_buffer_1bit i_buf2(.a(MemtoRegIn), .y(MemtoRegOut));
	delay_buffer_1bit i_buf3(.a(ALUresultIn), .y(ALUresultOut));
	delay_buffer_1bit i_buf4(.a(writeDstIn), .y(writeDstOut));
	delay_buffer_1bit i_buf5(.a(branchAddrIn), .y(branchAddrOut));
	
	DataMem i_DataMem(
	.clk(clk),
	.addr(ALUresultIn),
	.writeData(mt),
	.MemWrite(MemWrite),
	.MemRead(MemRead),
	.readData(readData),
	.reset(reset));
	
	assign doBra = Branch & zero;

endmodule
